DAC9767 DDS Signal Source Experiment, AD9767 datasheet and use the AD9767 to design a signal source that can generate sine, square, triangle, and sawtooth waves – FII-PRA040 Altera Risc-V Experiment 19
Experiment 19 DAC9767 DDS Signal Source Experiment
19.1 Experiment Objective
- Learn about DDS (Direct Digital Synthesizer) related theoretical knowledge.
- Read the AD9767 datasheet and use the AD9767 to design a signal source that can generate sine, square, triangle, and sawtooth waves.
19.2 Experiment Implement
- Learn about DDS theoretical knowledge.
- On the basis of understanding the principle of DDS, combined with the theoretical knowledge, use AD9767 module and development board to build a signal source whose waveform, amplitude and frequency can be adjusted. (There are no specific requirements for the adjustment of waveform, amplitude, and frequency here, as long as the conversion can be adjusted by pressing a button).
19.3 Experiment
19.3.1 DDS Introduction
The DDS technology is based on the Nyquist sampling theorem. Starting from the phase of the continuous signal, the sine signal is sampled, encoded, and quantized to form a sine function table, which is stored in the ROM. During synthesis, phase increment is changed by changing the frequency word of the phase accumulator. Phase increment is what is called step size. The difference in phase increment results in different sampling points in a cycle. When the clock frequency, or the sampling frequency does not change, the frequency is changed by changing the phase. The block diagram is shown in Figure 19.1.
Figure 19.1 DDS block diagram
19.3.2 AD9767 Configuration Introduction
The AD9767 module uses ADI’s AD9767 DAC chip, which is a 14-bit, 125MSPS conversion rate high-performance DAC device. It supports the IQ output mode and can be used in the communications.
AD9767 interface timing requirements. As shown in Figure 19.2 below, when the rising edge of the clock comes, the data must remain stable for ts time. After the rising edge of the clock, the data must remain stable for th to be correct.
Figure 19.2 9767 interface timing diagram
19.3.3 Waveform Memory File Configuration
The waveform storage area file is dds_4096x10b_wave_init.coe. For the specific making process, refer to the use of the *.coe file in the experiment 9. The file containing the waveform information is stored in the ROM. After the project file is programmed into the FPGA, the FPGA directly reads the waveform information from the ROM and sends it to the AD9767 interface, and then outputs the corresponding waveform on the AD9767 module. The waveform storage is as shown in Figure 19.3.
Figure 19.3 Wave file storage
19.3.4 Program Design
1.The main program includes waveform selection, mode selection, frequency adjustment, and amplitude adjustment. The specific code is as follows:
module dac_9767_test(
input wire sys_clk_50m, input wire rst_n, (*mark_debug=”true”*) output mode, output wire dac_clk, output wire led , input wire mode_adjust, input wire a_adjust, input wire f_adjust, input wire wave_adjust, output reg [13:0] data_out ); wire [9:0] douta ; wire clk_50m ; BUFG BUFG_inst ( .O(clk_50m), .I(sys_clk_50m) ); wire locked ; wire clk_100m ; pll_50_100 pll_50_100_inst ( .clk_out1(clk_100m), .clk_out2(dac_clk), //nclk_100m .reset(0), .locked(locked), .clk_in1(clk_50m)); reg rst_n_g = 0 ; always @ (posedge clk_100m) rst_n_g<=locked &rst_n ; wire A_ctrl ; wire F_ctrl ; wire wave_switch ; wire mode_ctrl ; reg [1:0] base_addr =0 ; reg [3:0] base_A =0 ; reg [1:0] a_st =0 ; always @ (posedge clk_100m , negedge rst_n_g ) begin if (~rst_n_g) base_addr <=0; else if (wave_switch) base_addr <= base_addr +1 ; else base_addr <= base_addr ; end always @ (posedge clk_100m , negedge rst_n_g ) begin if (~rst_n_g) begin base_A <=1; a_st <=0; end else begin case (a_st) 0: begin base_A <=8; a_st <=1; end 1: begin if (A_ctrl) begin a_st<=2 ; base_A <=11; end else begin a_st<=1 ; base_A <=8; end end 2: begin if (A_ctrl) begin a_st<=3; base_A <=15; end else begin a_st<=2; base_A <=11; end end 3: begin if (A_ctrl) begin a_st<= 1; base_A <=8; end else begin a_st<=3 ; base_A <=15; end end default :begin base_A <=1; a_st <=0; end endcase end end always @ (posedge clk_100m , negedge rst_n_g ) begin if (~rst_n_g) data_out <=0 ; else data_out<= douta * base_A ; end reg [9:0] addr_r =0; reg [9:0] addr_temp_F =1 ; reg [3:0] f_st =0 ; always @ (posedge clk_100m , negedge rst_n_g ) begin if (~rst_n_g) begin addr_temp_F <= 0; f_st <=0 ; end else begin case (f_st) 0 : begin addr_temp_F <= 0 ; f_st <= 1 ; end 1 : begin addr_temp_F <= 1 ; if (F_ctrl) f_st <= 2 ; end 2 : begin addr_temp_F <= 2 ; if (F_ctrl) f_st <= 3 ; end 3 : begin addr_temp_F <= 3 ; if (F_ctrl) f_st <= 4 ; end 4 : begin addr_temp_F <= 4 ; if (F_ctrl) f_st <= 5 ; end 5 : begin addr_temp_F <= 5 ; if (F_ctrl) f_st <= 6 ; end 6 : begin addr_temp_F <= 6 ; if (F_ctrl) f_st <= 7 ; end 7 : begin addr_temp_F <= 8 ; if (F_ctrl) f_st <= 1 ; end default : f_st <= 1 ; endcase end end always @ (posedge clk_100m , negedge rst_n_g ) begin if (~rst_n_g) addr_r <=0; else addr_r <=addr_r+1+addr_temp_F ; end (*mark_debug=”true”*)reg [11:0] addra=0 ; always @ (posedge clk_100m , negedge rst_n_g ) begin if (~rst_n_g) addra <=0 ; else addra<={base_addr, addr_r }; end reg mode_r=0; always @ (posedge clk_100m , negedge rst_n_g ) begin if (~rst_n_g) mode_r <=0 ; else if (mode_ctrl) mode_r <=~mode_r; else mode_r <= mode_r ; end assign mode=mode_r ; assign led= ~mode_r ; key_process ( .clk (clk_100m ) , .rst_n (rst_n_g ) , .key_switch (wave_adjust) , .key_adjust (a_adjust ) , .key_add (f_adjust ) , .key_sub (mode_adjust) , .flag_switch (wave_switch) , .flag_adjust (A_ctrl ) , .flag_add (F_ctrl ) , .flag_sub (mode_ctrl ) ); rom_dds_4096_10 rom_dds_4096_10_inst ( .clka(clk_100m), // input wire clka .addra(addra), // input wire [11 : 0] addra .douta(douta) // output wire [9 : 0] douta ); endmodule |
19.4 Experiment Verification
1. Pin assignment
Signal Name | Port Description | Network Name | FPGA Pin |
sys_clk_50m | System clock | C10_50MCLK | G21 |
mode | 9767 mode control | IO24 | AA14 |
wave_adjust | Waveform selection | key2 | V5 |
a_adjust | Amplitude selection | key3 | Y6 |
f_adjust | Frequency selection | key4 | AB4 |
mode_adjust | Mode selection | key6 | AA4 |
led | Mode indicator light | LED0 | J5 |
dac_clk | 9767 driving clock | IO28 | W13 |
rst_n | System reset | key1 | Y4 |
data_out[0] | AD9767 data bus | IO1 | U16 |
data_out[1] | AD9767 data bus | IO0 | AA15 |
data_out[2] | AD9767 data bus | IO5 | T16 |
data_out[3] | AD9767 data bus | IO4 | V16 |
data_out[4] | AD9767 data bus | IO3 | U17 |
data_out[5] | AD9767 data bus | IO6 | R16 |
data_out[6] | AD9767 data bus | IO2 | AB20 |
data_Out[7] | AD9767 data bus | IO7 | AA20 |
data_out[8] | AD9767 data bus | IO29 | AA13 |
data_out[9] | AD9767 data bus | IO30 | Y12 |
data_out[10] | AD9767 data bus | IO31 | Y13 |
data_out[11] | AD9767 data bus | IO27 | AB13 |
data_out[12] | AD9767 data bus | IO26 | AB14 |
data_out[13] | AD9767 data bus | IO25 | R14 |
2.Board verification
After the FPGA development board is programmed, press the right key (mode), and the mode indicator led0 lights up.
Then waveform can be chosen according to UP key (waveform selection), RETURN key (amplitude selection), LEFT key (frequency selection). (This experiment is only to introduce the theoretical knowledge of DDS and verify its correctness. Therefore, only four types of waveforms are set, which are sine wave, square wave, triangle wave, and sawtooth wave. The frequency and amplitude are also randomly set.) Figure 19.4 below shows four waveforms of the oscilloscope measuring the output of the 9767 module.
Figure 19-4a Sine wave Figure 19-4b Square wave
Figure 19-4c Triangle wave Figure 19-4d Sawtooth wave